using System;
using System.IO;
using System.Xml.Linq;
using Thunder.Vector.Model;
using Thunder.Vector.Model.Shapes;
using Thunder.Vector.Model.Units;

namespace Thunder.Vector.Formats
{
	public class SvgImporter : IImporter
	{
		public SvgImporter()
		{				
		}
		
		public Layer FromFile(string fileName)
		{
			return FromFile(new FileInfo(fileName));
		}
		
		public Layer FromFile(FileInfo file)
		{
			Layer root = new Layer(null);
			
			using (FileStream stream = file.OpenRead())
			{
				using (StreamReader reader = new StreamReader(stream))
				{
					XDocument doc = XDocument.Load(reader);
					XElement xRoot = doc.Root;
					if (xRoot.Name.LocalName != "svg")
						throw new Exception();
					ParseLevel(root, xRoot);
				}
			}
			
			return root;
		}
		
		private void ParseLevel(Layer layer, XElement xElement)
		{
			foreach (XElement xChild in xElement.Elements())
			{
				Entity entity = null;
				
				switch (xChild.Name.LocalName) {
				case "g":
					Layer childLayer = new Layer(layer);
					ParseLevel(childLayer, xChild);
					entity = childLayer;
					break;
				case "rect":
					Rectangle rect = new Rectangle();
					rect.X = ParseUnit(layer, xChild, "x", false, true);
					rect.Y = ParseUnit(layer, xChild, "y", false, true);
					rect.W = ParseUnit(layer, xChild, "width", false, false);
					rect.H = ParseUnit(layer, xChild, "height", false, false);
					entity = rect;
					break;
				default:
					break;
				}
				
				if (entity != null)
				{
					entity.Parent = layer;
					layer.Children.Add(entity);
				}
			}
		}
		
		private static Unit ParseUnit(Entity parent, XElement element, string name, bool required, bool allowNegative)
		{
			XAttribute attr = element.Attribute(name);
			if (required && attr == null)
				throw new Exception("attr may not be null");
			Unit unit = Unit.Parse(parent, attr.Value);
			if (!allowNegative && unit.Value < 0)
				throw new Exception("attr may not be negative");
			return unit;
		}
	}
}

